﻿using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Threading;
using System.Threading.Tasks;
using UpperComputer.Core.Entities;
using YFurion.Application;
using YFurion.Application.EFCore.Extensions;
using YFurion.Utils;

namespace UpperComputer.Application
{
    public class BaseRolePermissionService : EFCoreApplicationService<BaseRolePermission, BaseRolePermissionDto, long, BaseRolePermissionResultRequestDto>, IBaseRolePermissionService
    {
        /// <summary>
        /// 查询角色
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        protected override IQueryable<BaseRolePermission> CreateFilteredQuery(BaseRolePermissionResultRequestDto input)
        {
            string[] permissionCodeArray = input.PermissionCodes;
            string[] roleCodeArr = input.RoleCodes;
            IQueryable<BaseRolePermission> query = base.CreateFilteredQuery(input)
                .Join(MSRepository.Slave1<BaseRole>().AsQueryable(), brp => brp.RoleCode, br => br.Code, (brp, br) => brp)
                .WhereIf(permissionCodeArray?.Length > 0, brp => permissionCodeArray.Contains(brp.PermissionCode))
                .WhereIf(roleCodeArr?.Length > 0, brp => roleCodeArr.Contains(brp.RoleCode));

            return query;
        }

        /// <summary>
        /// 删除角色权限
        /// </summary>
        /// <param name="roleCode"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task DeleteAsync(string roleCode, CancellationToken cancellationToken = default)
        {
            List<BaseRolePermission> baseRolePermissions = await MasterRepository.AsQueryable(brp => brp.RoleCode.Equals(roleCode)).ToListAsync(cancellationToken);
            await MasterRepository.DeleteNowAsync(baseRolePermissions, cancellationToken);
        }

        /// <summary>
        /// 分配权限
        /// </summary>
        /// <param name="roleCode"></param>
        /// <param name="menus"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task<List<BaseRolePermissionDto>> PermissionAsync(string roleCode, List<BaseMenuResultDto> menus, CancellationToken cancellationToken = default)
        {
            List<BaseRolePermissionDto> baseRolePermissionResultDtos = new List<BaseRolePermissionDto>();
            await DeleteAsync(roleCode, cancellationToken);
            for (int i = 0; i < menus.Count; ++i)
            {
                BaseMenuResultDto menu = menus[i];
                BaseRolePermissionDto rolePermissionInput = new BaseRolePermissionDto
                {
                    Id = YIDGenerator.NextId(),
                    RoleCode = roleCode,
                    PermissionCode = menu.Type == 1 ? menu.Code : menu.ParentCode + menu.Code,
                    Type = menu.Type,
                    Sort = i + 1
                };
                BaseRolePermissionDto baseRolePermissionResultDto = await Post(rolePermissionInput, cancellationToken);
                baseRolePermissionResultDtos.Add(baseRolePermissionResultDto);
            }
            return baseRolePermissionResultDtos;
        }
    }
}
